package com.ailanyin.common.utils;

import cn.hutool.core.io.FileUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ailanyin
 * @version 1.0
 * @since 2022/1/6 0006 上午 10:03
 */
public class LinuxUtil {

    private static String PROJECT_NAME;

    public static void createJarService(String jarName,String filePath) {

        if (checkFileIsExist()) {
            System.out.println("/etc/systemd/system/"+jarName+".Service 文件已存在,创建Service中止！");
            return;
        }

        PROJECT_NAME = jarName;
        jarName = filePath + "/" + jarName;
        createFiles(jarName);
        createStartShell(jarName);
        createStopShell(jarName);
        addPersmission(jarName);
        createServiceShell(jarName);
        handleService(jarName);

    }

    private static void createStartShell(String jarName) {
        List<String> list = new ArrayList<>();
        list.add("#!/bin/bash");
        list.add("export JAVA_HOME=/opt/jdk1.8");
        list.add("export JRE_HOME=/opt/jdk1.8/jre");
        list.add("export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH");
        list.add("export PATH=$JAVA_HOME/bin:$PATH");
        list.add("nohup java -jar "+ jarName + ".jar  >" + jarName + ".out 2>&1 &");
        list.add("echo $! > /var/run/" + jarName + ".pid");
        cn.hutool.core.io.FileUtil.writeLines(list, jarName + "-start.sh", "UTF-8", false);
    }

    private static void createStopShell(String jarName) {
        List<String> list = new ArrayList<>();
        list.add("#!/bin/bash");
        list.add("PID=$(cat /var/run/" + jarName + ".pid)");
        list.add("kill -9 $PID");
        cn.hutool.core.io.FileUtil.writeLines(list, jarName + "-stop.sh", "UTF-8", false);
    }

    private static void createServiceShell(String jarName) {
        List<String> list = new ArrayList<>();
        list.add("[Unit]");
        list.add("Description=service for description");
        list.add("After=syslog.target network.target remote-fs.target nss-lookup.target");
        list.add("");
        list.add("[Service]");
        list.add("User=root");
        list.add("Type=forking");
        list.add("ExecStart=/bin/sh " + jarName + "-start.sh");
        list.add("ExecStop=/bin/sh " + jarName + "-stop.sh");
        list.add("");
        list.add("[Install]");
        list.add("WantedBy=multi-user.target");
        FileUtil.writeLines(list,  jarName + ".service", "UTF-8", false);
    }

    private static void addPersmission(String jarName) {
        shell("chmod +x " + jarName + "-start.sh");
        shell("chmod +x " + jarName + "-stop.sh");
        shell("chmod +x " + jarName + ".service");
    }

    private static void handleService(String jarName) {
        shell("mv " + jarName + ".service /etc/systemd/system/" + PROJECT_NAME + ".service");
        shell("systemctl daemon-reload");
        shell("systemctl enable " + PROJECT_NAME);
    }

    private static void createFiles(String jarName) {
        createFile( jarName + "-start.sh");
        createFile( jarName + "-stop.sh");
        createFile( jarName + ".service");
    }

    private static void createFile(String path) {
        // 新建文件
        File newFile = new File(path);
        if (!newFile.exists()) {
            try {
                if (!newFile.createNewFile()) {
                    System.out.println(path + "创建失败！");
                } else {
                    System.out.println("成功创建文件: " + path);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * linux执行shell
     *
     * ("sh", "-c" 可以执行复杂命令)
     * @param shell 命令
     */
    public static void shell(String shell) {
        String[] cmd = new String[]{"sh", "-c", shell};
        try {
            Runtime.getRuntime().exec(cmd);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static boolean checkFileIsExist() {
        File file = new File("/etc/systemd/system"+PROJECT_NAME+".service");
        return file.exists();
    }
}
